import { defineComponent, markRaw, ref, watch } from 'vue'
import DataNode from '../../ItemNode/DataNode'
import {
  ElColorPicker,
  ElInput,
  ElInputNumber,
  ElRadioButton,
  ElRadioGroup,
  ElStatistic,
  ElText
} from 'element-plus'
import classes from '../../ItemNode/ItemNode.module.css'
import { useTransition } from '@vueuse/core'
import NumFlip from './NumFlip.vue'
import NumFlipRaw from './NumFlip.vue?raw'

export default class NStatistic extends DataNode {
  isNStatistic = true
  isDataDisplayNode = true

  constructor(node?: NStatistic) {
    super(node)

    if (!node) {
      this.path = './components/NStatistic/NStatistic.tsx'
      this.name = '统计数'

      this.props.style = {
        ...this.props.style
      }

      this.props.valueStyle = {
        color: '#333',
        fontSize: '20px',
        fontWeight: 'normal'
      }

      this.props.dataUrl = ''
      this.props.dataFn = 'function () {\n  return Number\n}'
      this.props.value = 0
      this.props.precision = 0
      this.props.type = 'base'
      this.props.title = ''
      this.props.prefix = ''
      this.props.suffix = ''
      this.props.duration = 0
      this.props.groupSeparator = ','
    }

    const pComponent = this.component
    this.component = markRaw(
      defineComponent(
        (props) => {
          // 动效
          let source = ref(0)
          let value: any = useTransition(source, {
            duration: this.props.duration
          })

          source.value = this.props.value

          watch(
            () => this.props.data,
            () => {
              if (this.props.dataFnable) {
                source.value = this.props.value = isNaN(this.props.data)
                  ? 0
                  : Number(this.props.data)
              }
            },
            { immediate: true }
          )

          return () => (
            <pComponent>
              {() => {
                if (this.props.type === 'base')
                  return (
                    <ElStatistic
                      value={this.props.duration ? value.value : this.props.value}
                      precision={this.props.precision}
                      prefix={this.props.prefix}
                      suffix={this.props.suffix}
                      valueStyle={this.props.valueStyle}
                      groupSeparator={this.props.groupSeparator}
                      style={{
                        '--el-statistic-content-color': this.props.valueStyle.color,
                        '--el-statistic-content-font-size': `calc(${this.props.valueStyle.fontSize} * 0.7)`
                      }}
                    >
                      {{
                        title: this.props.title ? () => this.props.title : null
                      }}
                    </ElStatistic>
                  )
                else if (this.props.type === 'flip') {
                  return (
                    <NumFlip
                      key={Math.random()}
                      value={this.props.value}
                      valueStyle={this.props.valueStyle}
                      duration={this.props.duration}
                    ></NumFlip>
                  )
                }
              }}
            </pComponent>
          )
        },
        {
          name: 'NStatistic'
        }
      )
    )

    const pView = this.view
    this.view = markRaw(
      defineComponent((props) => {
        this.props.valueStyle.color = '#aaa'

        return () => (
          <pView>
            <this.component style={{ width: '100px', transform: 'scale(0.8)' }}></this.component>
          </pView>
        )
      })
    )

    const pParams = this.params
    this.params = markRaw(
      defineComponent(() => {
        return () => (
          <pParams>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                值
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInputNumber
                  modelValue={this.props.value}
                  onUpdate:modelValue={(v) => (this.props.value = isNaN(v) ? 0 : Number(v))}
                  size="small"
                ></ElInputNumber>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                标题
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.title} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                字色
              </ElText>
              <div class={classes['params-item-content']}>
                <ElColorPicker
                  modelValue={this.props.valueStyle.color}
                  onUpdate:modelValue={(v) => (this.props.valueStyle.color = v || '')}
                  show-alpha
                  size="small"
                  teleported={false}
                ></ElColorPicker>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                字体大小
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.valueStyle.fontSize} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                字体粗细
              </ElText>
              <div class={classes['params-item-content']}>
                <ElRadioGroup v-model={this.props.valueStyle.fontWeight}>
                  <ElRadioButton value="normal" label="正常" size="small"></ElRadioButton>
                  <ElRadioButton value="bold" label="加粗" size="small"></ElRadioButton>
                </ElRadioGroup>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                数字精度
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInputNumber
                  v-model={this.props.precision}
                  min={0}
                  step={1}
                  size="small"
                ></ElInputNumber>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                展示类型
              </ElText>
              <div class={classes['params-item-content']}>
                <ElRadioGroup v-model={this.props.type}>
                  <ElRadioButton value="base" label="基础" size="small"></ElRadioButton>
                  <ElRadioButton value="flip" label="翻牌" size="small"></ElRadioButton>
                </ElRadioGroup>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                动效时间
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInputNumber
                  v-model={this.props.duration}
                  min={0}
                  placeholder="毫秒"
                  size="small"
                ></ElInputNumber>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                前缀
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.prefix} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                后缀
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.suffix} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                千分位标识符
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.groupSeparator} size="small"></ElInput>
              </div>
            </div>
          </pParams>
        )
      })
    )
  }

  toVue(): SfcObj {
    const sfcObj = super.toVue()
    const name = sfcObj.name
    const dataVar = sfcObj.dataVar
    const [uuid0, uuid1] = this.uuid.split('-')
    const valueVar = `${name}_${uuid0}_valueVar`
    const sourceVar = `${name}_${uuid0}_sourceVar`
    const dynamicValueVar = `${name}_${uuid0}_dynamicValueVar`

    sfcObj.imports = {
      ...sfcObj.imports,
      vue: {
        ...sfcObj.imports.vue,
        ref: 'ref',
        watch: 'watch'
      },
      ['@vueuse/core']: {
        useTransition: 'useTransition'
      },
      ['./imports/NumFlip.vue']: {
        default: 'NumFlip'
      },
      ['element-plus']: {
        ElStatistic: 'ElStatistic'
      }
    }

    sfcObj.importFiles = {
      ...sfcObj.importFiles,
      'NumFlip.vue': NumFlipRaw
    }

    sfcObj.script = `
${sfcObj.script}
const ${valueVar} = ref(${this.props.valueVar ?? 0})
const ${sourceVar} = ref(0)
const ${dynamicValueVar} = useTransition(${sourceVar}, {
  duration: ${this.props.duration}
})
${sourceVar}.value = ${valueVar}.value

watch(${dataVar}, () => {
  ${sourceVar}.value = = ${valueVar}.value = isNaN(${dataVar}.value) ? 0 : Number(${dataVar}.value)
})
      `

    sfcObj.template = sfcObj.template.replace(
      '<slot></slot>',
      `
  ${
    this.props.type === 'base'
      ? `<ElStatistic
        :value="${this.props.duration ? dynamicValueVar : valueVar}"
        :precision="${this.props.precision}"
        prefix="${this.props.prefix}"
        suffix="${this.props.suffix}"
        :valueStyle="${JSON.stringify(this.props.valueStyle).replaceAll('"', "'")}"
        groupSeparator="${this.props.groupSeparator}"
        style="--el-statistic-content-color: ${this.props.valueStyle.color}; --el-statistic-content-font-size: calc(${this.props.valueStyle.fontSize} * 0.7)"
      >
      ${this.props.title ? ` <template #title>${this.props.title}</template>` : ''}
      </ElStatistic>`
      : ''
  }
  ${
    this.props.type === 'flip'
      ? `<NumFlip
          :value="${valueVar}"
          :valueStyle="${JSON.stringify(this.props.valueStyle).replaceAll('"', "'")}"
          :duration="${this.props.duration}"
        ></NumFlip>`
      : ''
  }
      `
    )

    return sfcObj
  }
}
